package com.ymatou.iapi.optrade.testcase;

import java.math.BigDecimal;

import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.google.common.collect.Lists;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.req.ConfirmReceiveReq;
import com.ymatou.iapi.optrade.parameter.req.CustomsClearanceUnfreezeOrderReq;
import com.ymatou.iapi.optrade.parameter.utill.Utils;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.service.ConfirmReceiveCall;
import com.ymatou.iapi.optrade.service.CustomsClearanceCall;
import com.ymatou.iapi.optrade.service.RefundService;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P3;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.database.sharding.db.sharding.model.AutoReceiveOptPo;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.OrderStatusLogPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.utils.constant.ECode;

/**
 * 买家确认收货 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_ConfirmReceive {

	private static ConfirmReceiveReq confirmReceiveReq;
	private static ConfirmReceiveCall confirmreceivecall;
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("买家确认收货");
	}

	@Before
	public void caseUp() {

		confirmReceiveReq = new ConfirmReceiveReq();
		confirmreceivecall = new ConfirmReceiveCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(confirmreceivecall.getOpurl());
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	/**
	 * 贝海物流，清关 解冻
	 * @param billNos
	 * @throws Exception
	 */
	public static void callCustomsClearanceCall(String... billNos)
			throws Exception {

		CustomsClearanceUnfreezeOrderReq customsClearanceUnfreezeOrderReq = new CustomsClearanceUnfreezeOrderReq();
		CustomsClearanceCall customsClearanceCall = new CustomsClearanceCall();

		customsClearanceUnfreezeOrderReq.setLogisticsNos(Lists
				.newArrayList(billNos));

		customsClearanceCall.setData(customsClearanceUnfreezeOrderReq);

		customsClearanceCall.callService();

	}

	/**
	 * 校验订单表状态，单主状态操作日志表
	 */
	public static void verifyOrderStatus(long orderId, String remark,
			long buyerId) {

		// 订单表(order)
		OrderPo ymtOrders = orderShardingWapper.selectOrderbyOrderId(orderId);

		Logger.comment(String.format("验证订单表(order)表 orderId: %s", orderId));

		Logger.verifyEquals(4, ymtOrders.getOrderStatus(), "验证orderStatus");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(ymtOrders.getReceiveTime()) < 2,
				"验证数据库deliveryTime跟系统当前时间差为2分钟内");

		//订单主状态操作日志表(order_status_log)
		OrderStatusLogPo orderStatusLogPo = orderShardingWapper
				.selectOrderStatusLogByOrderId(orderId);

		Logger.comment("验证订单主状态操作日志表(order_status_log)");

		Logger.verifyEquals(remark, orderStatusLogPo.getMemo(), "验证数据库Memo");
		Logger.verifyEquals(4, orderStatusLogPo.getOrderStatus(),
				"验证数据库OrderStatus");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(orderStatusLogPo.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(orderId, orderStatusLogPo.getOrderId(),
				"验证数据库OrderId");
		Logger.verifyEquals(buyerId, orderStatusLogPo.getOperator(),
				"验证数据库Operator");

		AutoReceiveOptPo autoReceiveOptPo = orderShardingWapper
				.selectAutoReceiveOptByOrderId(orderId);

		Logger.verifyEquals(true, autoReceiveOptPo.getFinish(), "验证数据库finish");

	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_ConfirmReceive_001() {
		Logger.start(true, "非贝海直邮订单买家确认收货成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getTradingId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();
			//订单支付
			TradingCallService.payOrder(userId, useAccountAmount, tradingId);
			//接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			//发货
			TradingCallService.delivery(sellerId, orderId, LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			confirmReceiveReq.setIgnoreXloboSignedCheck(true);
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.SUCCESS, confirmreceivecall.getCode(),
					"验证Code");
			// 数据库验证
			verifyOrderStatus(orderId, confirmReceiveReq.getRemark(),
					confirmReceiveReq.getBuyerId());
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_ConfirmReceive_002() {
		Logger.start(true, "IgnoreXloboSignedCheck 为false  贝海物流订单清关7天后，确认收货成功");
		try {
			Logger.comment("前置数据准备结束");

			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			//自动确认收货时间操作表（auto_receive_opt） 
			AutoReceiveOptPo record = new AutoReceiveOptPo();
			record.setFreeze(false);
			record.setOrderId(orderId);
			record.setExpectReceiveTime(DateTime.now().plusDays(-7).toDate());

			//修改预期自动确认收货时间为7天前
			orderShardingWapper.autoReceiveOptMapper
					.updateByPrimaryKeySelective(record);

			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			confirmReceiveReq.setIgnoreXloboSignedCheck(false);
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();

			Logger.verifyEquals(ECode.SUCCESS, confirmreceivecall.getCode(),
					"验证Code");

			// 数据库验证
			verifyOrderStatus(orderId, confirmReceiveReq.getRemark(),
					confirmReceiveReq.getBuyerId());

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_ConfirmReceive_003() {
		Logger.start(true,
				"IgnoreXloboSignedCheck 为false  贝海物流订单清关不到7天，确认收货成功失败");
		try {

			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			//自动确认收货时间操作表（auto_receive_opt） 
			AutoReceiveOptPo record = new AutoReceiveOptPo();
			record.setFreeze(false);
			record.setOrderId(orderId);
			record.setExpectReceiveTime(DateTime.now().plusDays(1).toDate());

			//修改预期自动确认收货时间为7天前
			orderShardingWapper.autoReceiveOptMapper
					.updateByPrimaryKeySelective(record);

			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			confirmReceiveReq.setIgnoreXloboSignedCheck(false);
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();

			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");

			Logger.verifyEquals("102", confirmreceivecall.getBCode(), "验证bcode");
			Logger.verifyEquals("哈尼，全部贝海运单签收后或清关完成后超过7天，订单才能确认收货哦",
					confirmreceivecall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_ConfirmReceive_004() {
		Logger.start(true,
				"IgnoreXloboSignedCheck 为false  贝海物流订单，所有面单都已签收，确认收货成功");
		try {
			Logger.comment("前置数据准备结束");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();

			//发货
			TradingCallService.delivery(sellerId, orderId, true);

			String billNo1 = "DB11320536300";
			String billNo2 = "DB11320536310";

			// 码头保存物流单号
			TradingCallService.saveDeliverSummary(orderId, sellerId, billNo1);
			// 码头保存物流单号
			TradingCallService.saveDeliverSummary(orderId, sellerId, billNo2);

			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			confirmReceiveReq.setIgnoreXloboSignedCheck(false);
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();

			Logger.verifyEquals(ECode.SUCCESS, confirmreceivecall.getCode(),
					"验证Code");

			// 数据库验证
			verifyOrderStatus(orderId, confirmReceiveReq.getRemark(),
					confirmReceiveReq.getBuyerId());

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_ConfirmReceive_005() {
		Logger.start(true,
				"IgnoreXloboSignedCheck 为false  贝海物流订单，有面单未签收，确认收货失败");
		try {
			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();

			//发货
			TradingCallService.delivery(sellerId, orderId, true);

			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			confirmReceiveReq.setIgnoreXloboSignedCheck(false);
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");

			Logger.verifyEquals("102", confirmreceivecall.getBCode(), "验证bcode");
			Logger.verifyEquals("哈尼，全部贝海运单签收后或清关完成后超过7天，订单才能确认收货哦",
					confirmreceivecall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_ConfirmReceive_006() {
		Logger.start(false, "买家重复确认收货");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderConfirmReceive();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");

			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();

			Logger.verifyEquals(ECode.SUCCESS, confirmreceivecall.getCode(),
					"验证Code");
			// 数据库验证
			verifyOrderStatus(orderId, confirmReceiveReq.getRemark(),
					confirmReceiveReq.getBuyerId());

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_ConfirmReceive_007() {
		Logger.start(false, "用户不是订单所有者");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId + 1);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");

			Logger.verifyEquals(
					String.format("买家%s没有操作订单%s的权限",
							confirmReceiveReq.getBuyerId(), orderId, userId),
					confirmreceivecall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_ConfirmReceive_008() {
		Logger.start(false, "用户id不存在");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmReceiveReq.setBuyerId(1);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");

			Logger.verifyEquals(
					String.format("买家%s没有操作订单%s的权限",
							confirmReceiveReq.getBuyerId(), orderId, userId),
					confirmreceivecall.getMsg(), "验证msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_ConfirmReceive_009() {
		Logger.start(false, "用户id为null");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			// confirmReceiveReq.setBuyerId(1);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");

			Logger.verifyEquals(
					String.format("买家%s没有操作订单%s的权限", 0, orderId, userId),
					confirmreceivecall.getMsg(), "验证msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_ConfirmReceive_010() {
		Logger.start(false, "订单号不存在");
		try {
			long orderId = 1111;
			confirmReceiveReq.setBuyerId(1113);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");
			Logger.verifyEquals(String.format("订单号%s不存在", confirmReceiveReq.getOrderId()),
					confirmreceivecall.getString("msg"), "验证接口返回消息");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_ConfirmReceive_011() {
		Logger.start(false, "订单号为null");
		try {
			confirmReceiveReq.setBuyerId(1113);
			// confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.ERROR400, confirmreceivecall.getCode(),
					"验证Code");
			Logger.verifyEquals("orderId:订单号未提供",
					confirmreceivecall.getString("msg"), "验证接口返回消息");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_ConfirmReceive_013() {
		Logger.start(true, "订单在退款退货中，确认收货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();
			//申请退款
			RefundService.applyRefund(placeOrderResp.getOrderList().get(0));

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");
			Logger.verifyEquals(ECode.ErrStatusNotMatch,
					confirmreceivecall.getBCode(), "验证bcode");
			Logger.verifyEquals("哈尼，关于该订单，您有未完成的退单,请完成退单流程或者撤销退单再确认收货哦~",
					confirmreceivecall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_ConfirmReceive_014() {
		Logger.start(true, "订单锁定中，确认收货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			//锁定订单
			TradingCallService.markOrderLock(orderId, 1);

			Logger.comment("前置数据准备结束");
			// 确认收货请求
			confirmReceiveReq.setBuyerId(userId);
			confirmReceiveReq.setOrderId(orderId);
			confirmReceiveReq.setRemark("收到了啊");
			// 发送请求
			confirmreceivecall.setData(confirmReceiveReq);
			confirmreceivecall.callService();
			Logger.verifyEquals(ECode.FAILED201, confirmreceivecall.getCode(),
					"验证Code");
			Logger.verifyEquals(ECode.ErrStatusNotMatch,
					confirmreceivecall.getBCode(), "验证bcode");
			Logger.verifyEquals("该订单已被客服锁定，暂时无法对该订单进行后续操作",
					confirmreceivecall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
